/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package CONTROLLERS;

import BEANS.ComboItem;
import BEANS.Product;
import UTIL.DatabaseConnector;
import UTIL.InputValidator;
import UTIL.TableManager;
import VIEW.ProductsUI;
import datechooser.beans.DateChooserCombo;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;

/**
 *
 * @author Belthazod
 */
public class DeliveryController {
    private DatabaseConnector dbConnector = DatabaseConnector.getInstance();
    private TableManager deliveryProductsTableManager;
    private TableManager deliveryTableManager;
    private TableManager deliveryHistoryTableManager;
    private JComboBox<ComboItem> deliveryProductFilterSupplierComboBox;
    private JLabel deliverySupplierLabel;
    private JLabel deliverySupplierIDLabel;
    private static ProductController productController;
    private static ArrayList<Product> productList;
    private JComboBox<ComboItem> productFilterCategoryComboBox;
    private JLabel clearMark;
    private JTextField productSearchInput;
    private JTextField quantityInput;
    private JTextField editQuantity;
    private JTextField deliveryReceiptNumberInput;
    private JDialog quantityInputDialog;
    private JDialog quantityEditDialog;
    private JTextArea remarksInput;
    private DateChooserCombo dateTo;
    private DateChooserCombo dateFrom;
    private DateChooserCombo deliveryDate;
    
    /**
     * Creates and instance of <code>DeliveryController</code> based on the given UI components to be manipulated
     * @param deliveryProductsTable - the <code>JTable</code> containing the list of all products in the inventory system
     * @param deliveryTable - the <code>JTable</code> containing the list of all products received from delivery
     * @param deliveryProductFilterSupplierComboBox - the <code>JComboBox</code> containing the list of suppliers to filter the Products in the Inventory System
     * @param deliverySupplierComboBox - the <code>JComboBox</code> containing the list of suppliers to identify from whom the delivery came from.
     */
    public DeliveryController(JTextField productSearchInput, JLabel clearMark, 
            JTable deliveryProductsTable, JTable deliveryTable, 
            JComboBox<ComboItem> productFilterCategoryComboBox, 
            JComboBox<ComboItem> deliveryProductFilterSupplierComboBox, 
            JLabel deliverySupplierLabel, JLabel deliverySupplierIDLabel,
            JDialog quantityInputDialog, JTextField quantityInput,
            JTextField editQuantity, JDialog quantityEditDialog, 
            JTextField deliveryReceiptNumberInput,JTextArea remarksInput,  
            JTable historyTable, DateChooserCombo dateTo, DateChooserCombo dateFrom,
            DateChooserCombo deliveryDate){
        try{
        this.deliveryDate = deliveryDate;
        this.productSearchInput = productSearchInput;
        this.clearMark = clearMark;
        this.deliveryProductsTableManager = new TableManager(deliveryProductsTable);
        this.deliveryTableManager = new TableManager(deliveryTable);
        this.productFilterCategoryComboBox = productFilterCategoryComboBox;
        this.deliveryProductFilterSupplierComboBox = deliveryProductFilterSupplierComboBox;
        this.deliverySupplierLabel= deliverySupplierLabel;
        this.productController = new ProductController();
        this.deliverySupplierIDLabel = deliverySupplierIDLabel;
        this.quantityInputDialog = quantityInputDialog;
        this.quantityInput = quantityInput;
        this.quantityEditDialog = quantityEditDialog;
        this.editQuantity = editQuantity;
        this.deliveryReceiptNumberInput = deliveryReceiptNumberInput;
        productList = ProductController.getProductList();
        deliveryProductsTableManager.alignCellRight(4);
        deliverySupplierIDLabel.setVisible(false);
        this.remarksInput = remarksInput;
        deliveryProductsTableManager.hideColumn(6);
        this.deliveryHistoryTableManager = new TableManager(historyTable);
        this.dateFrom = dateFrom;
        this.dateTo = dateTo;
        
        Calendar day = Calendar.getInstance();
        day.set(day.get(Calendar.YEAR), day.get(Calendar.MONTH), day.get(Calendar.DATE));
        day.add(Calendar.MONTH, -1);
        dateFrom.setSelectedDate(day);
        }catch(NullPointerException npe){
            
        }
    }
    
    /**
     * Copies the selected product details from the Delivery Products Table
     * to the DeliverySummary Table.
     */
    public void addSelectedToDeliverySummary(){
        
        boolean itemExists = false;
        try{
           // String productID = deliveryProductsTableManager.getIDFromTable(deliveryProductsTableManager.getSelectedRow());
            String itemSupplier = deliveryProductsTableManager.getValueAt(deliveryProductsTableManager.getSelectedRow(), 3);
            
            Object supplierComboBoxitem = deliveryProductFilterSupplierComboBox.getSelectedItem();
            String itemSupplierID = deliveryProductsTableManager.getValueAt(deliveryProductsTableManager.getSelectedRow(), 6);
            
            String deliverySupplier = deliverySupplierLabel.getText();
            if(itemSupplier.equals(deliverySupplier) || deliverySupplier.equals("")){
                quantityInputDialog.setVisible(true);
            }else{
                int result = JOptionPane.showConfirmDialog(null, "The supplier of the item you are adding does not match the supplier of the delivery list.\n\n Clear the current delivery list to accomodate the new item.", "Suppliers Error", JOptionPane.YES_NO_OPTION);
                if (result == 0){
                    deliverySupplierLabel.setText(itemSupplier);
                    deliverySupplierIDLabel.setText(itemSupplierID);
                    deliveryTableManager.clearTableContents();
                    addSelectedToDeliverySummary();
                }
            }
        }catch(IndexOutOfBoundsException ioobe){
            ioobe.printStackTrace();
            JOptionPane.showMessageDialog(null, "Please select a Product", "Selection Error", JOptionPane.ERROR_MESSAGE);
        }
    }
    
    public void quantityInput(){
        try{
        boolean itemExists = false;
            String productID = deliveryProductsTableManager.getIDFromTable(deliveryProductsTableManager.getSelectedRow());
            String currentQuantity = deliveryProductsTableManager.getValueAt(deliveryProductsTableManager.getSelectedRow(), 4);
            String itemSupplier = deliveryProductsTableManager.getValueAt(deliveryProductsTableManager.getSelectedRow(), 3);
            
            String itemSupplierID = deliveryProductsTableManager.getValueAt(deliveryProductsTableManager.getSelectedRow(), 6);
            
            String quantity = quantityInput.getText(); 
            int quant = Integer.parseInt(quantity);
         
        for(int row = 0; row < deliveryTableManager.getRowCount(); row++){
                    String truckProductID = deliveryTableManager.getIDFromTable(row);
                    itemExists = productID.equals(truckProductID);
                }
                if(itemExists){
                    JOptionPane.showMessageDialog(null,
                        "Item already added.",
                        "Error",
                        JOptionPane.ERROR_MESSAGE);
                }else if(quant < 1){
                    JOptionPane.showMessageDialog(null, "Please enter a valid quantity.", "Quantity Error", JOptionPane.ERROR_MESSAGE);
                }else{
                    //if(isNumeric(quantity)){
                    String name = (String) deliveryProductsTableManager.getValueAt(deliveryProductsTableManager.getSelectedRow(), 1);
                    String unit = (String) deliveryProductsTableManager.getValueAt(deliveryProductsTableManager.getSelectedRow(), 3);

                    deliveryTableManager.addRowContent(new String[]{productID, name, unit, quantity});
                    deliverySupplierLabel.setText(itemSupplier);
                    deliverySupplierIDLabel.setText(itemSupplierID);
                    quantityInputDialog.dispose();
                    /*}else{
                        JOptionPane.showMessageDialog(null, "Please enter the quantity.", "Input Error", JOptionPane.ERROR_MESSAGE);
                    }*/
                }
         }catch(NumberFormatException nfe){
             JOptionPane.showMessageDialog(null, "Please enter a valid quantity.", "Quantity Error", JOptionPane.ERROR_MESSAGE);
         }
                        
    }
    
    public static boolean isNumeric(String str){  
    try{  
    int string = Integer.parseInt(str);  
    }  
    catch(NumberFormatException nfe)  
    {  
    return false;  
    }  
    return true;  
    }
    /**
     * Removes the selected row in the Delivery Summary<code>JTable</code>
     */
    public void removeSelectedRow(){
        deliveryTableManager.deleteRow();
    }
    
    public void clearList(){
        int result = JOptionPane.showConfirmDialog(null, "Are you sure you want to clear the list?", "Confirm Checkout", JOptionPane.YES_NO_OPTION);
        if(result == 0){
        deliveryTableManager.clearTableContents();
        deliverySupplierLabel.setText("");
    }
    }
    /**
     * Filters the Products in the Products <code>JTable</code> to show only products 
     * coming from a particular supplier.
     */
    
    public void filterProducts(){

         ArrayList<Product> productList = productController.getProducts();
        
         if(productFilterCategoryComboBox.getSelectedItem()!=null && productList != null && deliveryProductFilterSupplierComboBox.getSelectedItem()!=null){
            deliveryProductsTableManager.clearTableContents();
            ArrayList<Product> filteredByCategoryList = filterByCategory( productList);
            ArrayList<Product> filteredByCategoryAndSupplierList = filterBySupplier(filteredByCategoryList);
            
            if(clearMark.isVisible()){
                searchProduct();
            }else{
                for(Product product:filteredByCategoryAndSupplierList){

                        String[] productValues = {product.getProductID(), product.getName(), product.getTypeName(),
                        product.getSupplierName(),
                        product.getPhysicalCount(), 
                        product.getReorderQuantityLevel(), product.getSupplierID()};

                        deliveryProductsTableManager.addRowContent(productValues);
                  
                }
            }
         }        
    }
    
         public ArrayList<Product> filterByCategory(ArrayList<Product> productList){
         ArrayList<Product> filteredProductList = new ArrayList<Product>();
         if(productFilterCategoryComboBox.getSelectedItem().toString().equals("All")){
             return productList;
         }else{
            for(Product product:productList){
                if(productFilterCategoryComboBox.getSelectedItem().toString().equals(product.getTypeName())){
                    filteredProductList.add(product);
                }
            }
            return filteredProductList;
         }
     }
         
         public ArrayList<Product> filterBySupplier(ArrayList<Product> productList){
         ArrayList<Product> filteredProductList = new ArrayList<Product>();
         if(deliveryProductFilterSupplierComboBox.getSelectedItem().toString().equals("All")){
             return productList;
         }else{
            for(Product product:productList){
                if(deliveryProductFilterSupplierComboBox.getSelectedItem().toString().equals(product.getSupplierName())){
                    filteredProductList.add(product);
                }
            }
            return filteredProductList;
         }
     }
    
        public void searchProduct(){
        String productName = productSearchInput.getText();
        
        ArrayList<Product> productList = productController.getProducts();
        deliveryProductsTableManager.clearTableContents();
        
        ArrayList<Product> filteredByCategoryList = filterByCategory(productList);
        ArrayList<Product> filteredBySupplierAndCategoryList = filterBySupplier(filteredByCategoryList);
        for(Product product: filteredBySupplierAndCategoryList){
            if(product.getName().toLowerCase().contains(productName.toLowerCase())){
                String[] adminCompleteValues = {product.getProductID(), product.getName(), product.getTypeName(),
                     product.getSupplierName(),
                     product.getPhysicalCount(), 
                    product.getReorderQuantityLevel(), product.getSupplierID()};
                deliveryProductsTableManager.addRowContent(adminCompleteValues);
            }
        }
        if(productName.equals("")){
            clearMark.setVisible(false);
        }else{
            clearMark.setVisible(true);
        }
    }
    
    public void clearSearch(){
        productSearchInput.setText("");
        searchProduct();
        clearMark.setVisible(false);
    }
    
    
    
    public void editQuantityDialog(){
         try{
         String quantity = editQuantity.getText();
         int quant = Integer.parseInt(quantity);
         if(quant > 0){                  
         deliveryTableManager.setValueAt(deliveryTableManager.getSelectedRow(), 3, quantity);
         editQuantity.setText("");
         quantityEditDialog.dispose();
         }else{
             JOptionPane.showMessageDialog(null, "Please Input a valid quantity.", "Input Error", JOptionPane.ERROR_MESSAGE);
         }
         }catch(NumberFormatException nfe){
             JOptionPane.showMessageDialog(null, "Please Input a valid quantity.", "Input Error", JOptionPane.ERROR_MESSAGE);
         }
     }
    /**
     * Gets all the products enlisted in the "Delivery" <code>JTable</code> and 
     * creates a delivery and delivery_details topple(s) based on the values 
     * in the table.
     */
    public void acknowledgeDelivery(){
        DateFormat dffrom = new SimpleDateFormat("MMMMM d, yyyy");

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String dDate = deliveryDate.getText().split(",")[1].substring(1).concat(","+deliveryDate.getText().split(",")[2]);
        try{
            String supplierID = deliverySupplierIDLabel.getText();
            java.util.Date date = dffrom.parse(dDate);
            String dateOfDelivery = sdf.format(date);
            boolean orIsEmpty = false;
            boolean invalidQuantityFlag = false;
            for(int row = 0; row < deliveryTableManager.getRowCount();row++){
                int quantity = Integer.parseInt(deliveryTableManager.getValueAt(row, 3));
                if(quantity <= 0){
                    invalidQuantityFlag = true;
                    break;
                }
            }
            if(deliveryReceiptNumberInput.getText().equals("")){
                orIsEmpty = true;
            }
            
            if(!invalidQuantityFlag && !orIsEmpty){
                int result = JOptionPane.showConfirmDialog(null, "Confirm Delivery?", "Confirm Delivery", JOptionPane.YES_NO_OPTION);
                if(result == 0){
                dbConnector.insert("INSERT INTO delivery (supplier_id, date_order_received, delivery_receipt, remarks) VALUES(?,?,?,?)", 
                        new String[]{supplierID, dateOfDelivery, deliveryReceiptNumberInput.getText(), remarksInput.getText()});
                ResultSet rs = dbConnector.query("SELECT delivery_id FROM delivery ORDER BY 1 DESC");
                rs.next();
                String deliveryID = rs.getString(1);
                for(int row = 0; row < deliveryTableManager.getRowCount(); row++){
                    Integer quantityToTransfer = Integer.parseInt(deliveryTableManager.getValueAt(row, 3));
                        
                    String productID = deliveryTableManager.getIDFromTable(row);
                    if(quantityToTransfer > 0){
                        dbConnector.insert("INSERT INTO deliverydetails "
                                + "(delivery_id, product_id, quantity_delivered)"
                                + " VALUES(?,?,?)", 
                                new String[]{deliveryID, productID, quantityToTransfer.toString()});
                        dbConnector.update("UPDATE product SET physical_count = physical_count + ? WHERE product_id = ?", new String[]{quantityToTransfer.toString(),productID});
                        
                    }
                }
            
                deliveryTableManager.clearTableContents();
                ProductsUI.updateAdminProductsTable();
                filterProducts();
                deliverySupplierLabel.setText("");
                deliverySupplierIDLabel.setText("");
                deliveryReceiptNumberInput.setText("");
                remarksInput.setText("");
                dbConnector.closeConnection();
                JOptionPane.showMessageDialog(null, "Delivery Saved!", "Delivery Success", JOptionPane.INFORMATION_MESSAGE);
                
                //dbConnector.insert("INSERT INTO reports (date, transaction, product_name, quantity) VALUES(?,?,?,?)", new String[]{today.toString, "Delivery", asd);
                }
                }else if(orIsEmpty){
                    JOptionPane.showMessageDialog(null, "Please enter the delivery Receipt.");
                }else{
                JOptionPane.showMessageDialog(null, "Invalid Quantity", "Quantity Error", JOptionPane.ERROR_MESSAGE);
            }
        }catch(SQLException sqlE){
            sqlE.printStackTrace();
            JOptionPane.showMessageDialog(null, "Failed to save delivery", "Database error.", JOptionPane.ERROR_MESSAGE);
        }catch(IndexOutOfBoundsException ioobe){
            JOptionPane.showMessageDialog(null, "Please input the quantity of the item/s delivered.");
        }catch(NumberFormatException nfe){
            JOptionPane.showMessageDialog(null, "Please input a valid quantity.");
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    
    public void editDialog(){
        quantityEditDialog.setVisible(true);
    }
    
     public void justDClickIt(JTable table){
    table.addMouseListener(new MouseAdapter() {
    public void mousePressed(MouseEvent me) {
        JTable table =(JTable) me.getSource();
        Point p = me.getPoint();
        int row = table.rowAtPoint(p);
        if (me.getClickCount() == 2) {
            addSelectedToDeliverySummary();
        }
    }
});
    }
    
      public void justDClickIt2(JTable table){
    table.addMouseListener(new MouseAdapter() {
    public void mousePressed(MouseEvent me) {
        JTable table =(JTable) me.getSource();
        Point p = me.getPoint();
        int row = table.rowAtPoint(p);
        if (me.getClickCount() == 2) {
            editDialog();
        }
    }
});
    }
      
      public void updateDeliveryHistoryReport(){                        
        try{            
            deliveryHistoryTableManager.clearTableContents();
            DateFormat dfto = new SimpleDateFormat("yyyy-MM-dd");
            SimpleDateFormat sdf = new SimpleDateFormat("MMMMM d, yyyy");
            String toDate = InputValidator.dateFormat(dateFrom);
            String fromDate = InputValidator.dateFormat(dateTo);
            ResultSet rs = dbConnector.query("SELECT delivery_id, date_order_received, name, quantity_delivered, delivery_receipt, Supplier_name, remarks FROM delivery JOIN deliverydetails using(Delivery_id) JOIN product using(Product_id) JOIN supplier ON supplier.supplier_id = delivery.supplier_id WHERE date_order_received between '" + toDate + "' and '" + fromDate + "' ORDER BY 2 DESC");
            
            while(rs.next()){
                String date = rs.getString("date_order_received");
                java.util.Date dateFormat = dfto.parse(date);
                String dateReport = sdf.format(dateFormat);
                String name = rs.getString("name");
                String quantity = rs.getString("quantity_delivered");
                String description = rs.getString("delivery_receipt");
                String id = rs.getString("Supplier_name");
                String remarks = rs.getString("remarks");
                
                String[] reportDetails = {dateReport, name, quantity, description, remarks};
                deliveryHistoryTableManager.addRowContent(reportDetails);
            }
        }catch(SQLException sqlE){
            sqlE.printStackTrace();
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}
